package visual.servidor;


import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.JLabel;
import javax.swing.JTextField;

import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;

import apoio.FuncoesGerais;
import apoio.Tipos;
import apoio.Tipos.Tipo;
import atacado.IntAtacado;
import atacado.ServidorAtacado;
import basedados.arquivos_texto.TxtIObj;
import basedados.entidades.Empresas;
import basedados.entidades.HistoricoCompras;
import basedados.entidades.HistoricoConfiabilidade;
import basedados.entidades.Produtos;
import servidor.varejo.ServidorVarejo;
import visual.cadastros.empresas.frmCadEmpresas;
import visual.cadastros.produto.frmCadastrarProdutos;
import visual.cliente.frmCliente;
import visual.historicos.frmHistoricos;
import visual.testes.frmServerTeste;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComboBox;
import java.awt.Color;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * formulario servidor
 * @author Emerson Shigueo Sugimoto
 * */
public class frmServidor extends JFrame {
	private static final long serialVersionUID = 1L;
	private JPanel contentPane;
	private JTextField txtPorta;
	private JTextArea txtMensagensServidor;
	private JTextField txtNomeServico;
	private frmCadastrarProdutos _frmCadastrarProdutos;
	private JTextField txtCaixa;
	private JTextField txtGrauConfiabilidade;
	private frmHistoricos _frmHistoricos;
	private JComboBox cboRamo;
	private frmCadEmpresas _frmCadEmpresas;
	private Tipo _meutipo;
	private JTable JTableProdutos;
	private Produtos _produtos;
	private JTextArea txtRespostasCliente;
	private JPanel pnlServer;
	private JTabbedPane tabbedPane;
	
	//private List<Dados> _dados;
	private int _quantidadeComprar;
	private JPanel pnlAcoes;
	private JButton btnIniciar;
	
	private ServidorVarejo _servidorVarejo;
	private ServidorAtacado _servidorAtacado;
	private frmCliente _frmCliente;
	private JLabel lblInformacoesJtable;
	private JTextField txtPortaVarejo;
	private JTextField txtServicoVarejo;
	
	public void setProdutos(Produtos produtos) {this._produtos = produtos;}
	public Produtos getProdutos() {return _produtos;}
	public void setMeuTipo(Tipo meutipo) {this._meutipo = meutipo;}
	public Tipo getMeuTipo() {return _meutipo;}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					frmServidor frame = new frmServidor();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Cria o Frame
	 */
	public frmServidor() {
		setProdutos(new Produtos());
		
		setResizable(false);
		setTitle("Servidor - Meu Tipo: Livraria1");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 533, 415);
		contentPane = new JPanel();
		contentPane.setBackground(Color.WHITE);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				int selecionado = FuncoesGerais.recuperaCodigoCombo(cboRamo);
				setMeuTipo(Tipos.IntTipo(selecionado));
				
				if (tabbedPane.getSelectedComponent().equals(pnlAcoes)) {
					preencherJTableProdutos();
					
					lblInformacoesJtable.setText("Nao exibe produtos do meu ramo: " + getMeuTipo());
				}
			}
		});
		tabbedPane.setBounds(10, 11, 509, 370);
		contentPane.add(tabbedPane);
		
		pnlServer = new JPanel();
		pnlServer.setBackground(Color.WHITE);
		tabbedPane.addTab("Servidor", null, pnlServer, null);
		pnlServer.setLayout(null);
		
		JPanel pnlConfiguracoes = new JPanel();
		pnlConfiguracoes.setBounds(10, 11, 489, 97);
		pnlServer.add(pnlConfiguracoes);
		pnlConfiguracoes.setBorder(new TitledBorder(null, "Configura\u00E7\u00F5es Atacado", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		pnlConfiguracoes.setLayout(null);
		
		JLabel lblPorta = new JLabel("Porta:");
		lblPorta.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblPorta.setBounds(10, 25, 76, 14);
		pnlConfiguracoes.add(lblPorta);
		
		txtPorta = new JTextField();
		txtPorta.setFont(new Font("Dialog", Font.PLAIN, 11));
		txtPorta.setText("1999"); //porta default
		txtPorta.setBounds(95, 22, 141, 20);
		pnlConfiguracoes.add(txtPorta);
		txtPorta.setColumns(10);
		
		JLabel lblNomeServico = new JLabel("Servico:");
		lblNomeServico.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblNomeServico.setBounds(10, 45, 46, 14);
		pnlConfiguracoes.add(lblNomeServico);
		
		txtNomeServico = new JTextField();
		txtNomeServico.setText("Livraria1");
		txtNomeServico.setBounds(95, 45, 141, 20);
		pnlConfiguracoes.add(txtNomeServico);
		txtNomeServico.setColumns(10);
		
		JLabel lblCaixa = new JLabel("Caixa:");
		lblCaixa.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblCaixa.setBounds(246, 25, 76, 14);
		pnlConfiguracoes.add(lblCaixa);
		
		txtCaixa = new JTextField();
		txtCaixa.setFont(new Font("Tahoma", Font.PLAIN, 11));
		txtCaixa.setText("10000");
		txtCaixa.setBounds(331, 22, 141, 20);
		pnlConfiguracoes.add(txtCaixa);
		txtCaixa.setColumns(10);
		
		JLabel lblNewLabel = new JLabel("Confiabilidade:");
		lblNewLabel.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblNewLabel.setBounds(246, 45, 92, 14);
		pnlConfiguracoes.add(lblNewLabel);
		
		txtGrauConfiabilidade = new JTextField();
		txtGrauConfiabilidade.setFont(new Font("Tahoma", Font.PLAIN, 11));
		txtGrauConfiabilidade.setText("20.0");
		txtGrauConfiabilidade.setBounds(331, 45, 141, 20);
		pnlConfiguracoes.add(txtGrauConfiabilidade);
		txtGrauConfiabilidade.setColumns(10);
		
		JLabel lblRamo = new JLabel("Ramo:");
		lblRamo.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblRamo.setBounds(10, 70, 61, 14);
		pnlConfiguracoes.add(lblRamo);
		
		cboRamo = new JComboBox();
		cboRamo.setFont(new Font("Tahoma", Font.PLAIN, 11));
		cboRamo.setBounds(94, 70, 142, 20);
		Tipos.preencherCbo(cboRamo);
		cboRamo.setSelectedIndex(1); //meutipo - livraria
		pnlConfiguracoes.add(cboRamo);
		
		btnIniciar = new JButton("Iniciar");
		btnIniciar.setBounds(10, 177, 89, 23);
		pnlServer.add(btnIniciar);
		btnIniciar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				iniciarServidor();
			}
		});
		btnIniciar.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		JButton btnCadastrarProdutos = new JButton("Produtos");
		btnCadastrarProdutos.setBounds(99, 177, 89, 23);
		pnlServer.add(btnCadastrarProdutos);
		btnCadastrarProdutos.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		JButton btnHistoricos = new JButton("Historicos");
		btnHistoricos.setBounds(188, 177, 89, 23);
		pnlServer.add(btnHistoricos);
		btnHistoricos.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		JButton btnEmpresas = new JButton("Empresas");
		btnEmpresas.setBounds(277, 177, 89, 23);
		pnlServer.add(btnEmpresas);
		btnEmpresas.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (_frmCadEmpresas == null) _frmCadEmpresas = new frmCadEmpresas(new Empresas());
				_frmCadEmpresas.setVisible(true);
			}
		});
		btnEmpresas.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 211, 489, 122);
		pnlServer.add(scrollPane);
		
		txtMensagensServidor = new JTextArea();
		txtMensagensServidor.setFont(new Font("Dialog", Font.PLAIN, 11));
		txtMensagensServidor.setEditable(false);
		scrollPane.setViewportView(txtMensagensServidor);
		
		JButton btnCliente = new JButton("Cliente");
		//btnCliente.setVisible(false);
		btnCliente.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnCliente.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (_frmCliente==null) _frmCliente = new frmCliente();
				_frmCliente.setVisible(true);  
			}
		});
		btnCliente.setBounds(366, 177, 89, 23);
		pnlServer.add(btnCliente);
		
		JPanel panel = new JPanel();
		panel.setBorder(new TitledBorder(null, "Configura\u00E7\u00F5es Varejo", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel.setBounds(10, 118, 489, 48);
		pnlServer.add(panel);
		panel.setLayout(null);
		
		JLabel lblPorta_1 = new JLabel("Porta:");
		lblPorta_1.setBounds(10, 22, 72, 14);
		panel.add(lblPorta_1);
		
		txtPortaVarejo = new JTextField();
		txtPortaVarejo.setText("3645");
		txtPortaVarejo.setBounds(95, 22, 141, 20);
		panel.add(txtPortaVarejo);
		txtPortaVarejo.setColumns(10);
		
		JLabel lblServico = new JLabel("Servi\u00E7o:");
		lblServico.setBounds(246, 22, 63, 14);
		panel.add(lblServico);
		
		txtServicoVarejo = new JTextField();
		txtServicoVarejo.setText("Livraria1Varejo");
		txtServicoVarejo.setBounds(331, 22, 141, 20);
		panel.add(txtServicoVarejo);
		txtServicoVarejo.setColumns(10);
		
		JButton btnTesteVarioaServidores = new JButton("Teste");
		btnTesteVarioaServidores.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnTesteVarioaServidores.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				testeVariosServidores();
			}
		});
		btnTesteVarioaServidores.setBounds(465, 177, 34, 23);
		pnlServer.add(btnTesteVarioaServidores);
		
		pnlAcoes = new JPanel();
		pnlAcoes.setBackground(Color.WHITE);
		tabbedPane.addTab("Atacado", null, pnlAcoes, null);
		pnlAcoes.setLayout(null);
		
		JPanel pnlGetPreco = new JPanel();
		pnlGetPreco.setBorder(new TitledBorder(null, "Pre\u00E7o", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		pnlGetPreco.setBounds(10, 11, 484, 159);
		pnlAcoes.add(pnlGetPreco);
		pnlGetPreco.setLayout(null);
		
		JScrollPane scrollProdutos = new JScrollPane();
		scrollProdutos.setToolTipText("Produtos");
		scrollProdutos.setBounds(10, 22, 464, 101);
		pnlGetPreco.add(scrollProdutos);
		
		JTableProdutos = new JTable(getModelJTableProdutos());
		JTableProdutos.setBackground(Color.WHITE);
		JTableProdutos.setFont(new Font("Tahoma", Font.PLAIN, 11));
		scrollProdutos.setViewportView(JTableProdutos);
		
		JButton btnGetPreco = new JButton("get Preco e Compra");
		btnGetPreco.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				getPreco();
			}
		});
		btnGetPreco.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnGetPreco.setBounds(321, 128, 153, 23);
		pnlGetPreco.add(btnGetPreco);
		
		lblInformacoesJtable = new JLabel("");
		lblInformacoesJtable.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblInformacoesJtable.setBounds(10, 132, 212, 14);
		pnlGetPreco.add(lblInformacoesJtable);
		
		JButton btnPeloId = new JButton("Pelo id");
		btnPeloId.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnPeloId.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				int idProduto;
				try {
					idProduto = Integer.valueOf(apoio.Mensagens.input("Id Produto: "));
				} catch (Exception err){
					apoio.Mensagens.mensagemErro("Id Produto invalido", "Id Produto"); return;
				}
				
				try {
					_quantidadeComprar = Integer.valueOf(apoio.Mensagens.input("Digite a Quantidade: "));
				} catch (Exception err){
					apoio.Mensagens.mensagemErro("Quantidade invalida", "Quantidade"); return;
				}
				if (_quantidadeComprar <= 0) { apoio.Mensagens.mensagemErro("Quantidade invalida", "Quantidade"); return;}
				//Tipo tpProduto = Tipos.IntTipo(Integer.valueOf(tipoProduto));
				
				Produtos p = Produtos.getProduto(idProduto);
				clienteGetPreco(p.getCodigo(), p.getTipoProduto());
			}
		});
		btnPeloId.setBounds(225, 128, 89, 23);
		pnlGetPreco.add(btnPeloId);
		
		JScrollPane scrollRespostasCliente = new JScrollPane();
		scrollRespostasCliente.setBounds(10, 181, 484, 150);
		pnlAcoes.add(scrollRespostasCliente);
		
		txtRespostasCliente = new JTextArea();
		scrollRespostasCliente.setViewportView(txtRespostasCliente);
		btnHistoricos.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				showHistoricos();
			}
		});
		btnCadastrarProdutos.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (_frmCadastrarProdutos == null) _frmCadastrarProdutos = new frmCadastrarProdutos(new Produtos());
				_frmCadastrarProdutos.setVisible(true);
			}
		});
		
		//preencherJTableProdutos();
		
	}
	
	/**
	 * exibe o formulario de historicos de compras e de confiabilidade
	 * */
	private void showHistoricos(){
		_frmHistoricos = null;
		if (_frmHistoricos == null) _frmHistoricos = new frmHistoricos();
		_frmHistoricos.setVisible(true);
	}
	
	/**
	 * inicia o servidor de encomendas e de varejo
	 * */
	private void iniciarServidor(){
		if (txtPorta.getText().equals("")) {return;}
		txtPorta.setEnabled(false);
		txtNomeServico.setEnabled(false);
		txtCaixa.setEnabled(false);
		txtPortaVarejo.setEnabled(false);
		txtServicoVarejo.setEnabled(false);
		
		//btnIniciar.setEnabled(false);
		btnIniciar.setText("Reiniciar");
		cboRamo.setEnabled(false);
		
		int selecionado = FuncoesGerais.recuperaCodigoCombo(cboRamo);
		setMeuTipo(Tipos.IntTipo(selecionado));
		
		if (_servidorAtacado!=null){ _servidorAtacado.parar();}
		_servidorAtacado = null;
		
		//servidor de encomendas
		try {
			_servidorAtacado = new ServidorAtacado(
					Integer.valueOf(txtPorta.getText()), 
					txtNomeServico.getText(), txtMensagensServidor,
					txtGrauConfiabilidade, txtCaixa
					);
			_servidorAtacado.iniciar();
		} catch (RemoteException e2) {
			e2.printStackTrace();
		}
		
		//servidor varejo
		//if (_servidorVarejo=!=null) {_servidorVarejo.pa}
		_servidorVarejo = null;
		try {
			_servidorVarejo = new ServidorVarejo(
					txtServicoVarejo.getText(), 
					Integer.valueOf(txtPortaVarejo.getText()),
					txtMensagensServidor
					);
			_servidorVarejo.iniciar();
			
			//printMensagensServidor("Iniciando servidor de varejo ["+txtServicoVarejo.getText()+":"+txtPortaVarejo.getText()+"]");
			
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		
		preencherJTableProdutos();
	}
	
	/**
	 * @return Retorna o modelo do JTableProdutos
	 * */
	private DefaultTableModel getModelJTableProdutos(){
		return new DefaultTableModel(
				new String[][] {},
				getProdutos().getTitulosJTableApenasPesquisa()
				) {
			private static final long serialVersionUID = -2030171847248754625L;

			@Override
			public boolean isCellEditable(int row, int column) {
				// return super.isCellEditable(row, column);
				return false;
			}
		};
	}

	/**
	 * Preenche o JTableProdutos nao retorna produtos do meu ramo, simplificacao adotada
	 * pois nao ha sentido em requisitar produtos a outros atacadistas do ramo que sou especialista
	 * */
	private void preencherJTableProdutos(){
		if (getProdutos() == null) return;
		
		//table = null;
		//table = new JTable(getModel());
		DefaultTableModel modelo = (DefaultTableModel) JTableProdutos.getModel();
		modelo.setNumRows(0);
		if (modelo.getRowCount() > 0) {
			for(int i = 0; i < modelo.getRowCount(); i++) {  
				modelo.removeRow(i);
	        }  
		}
		// Adiciona uma nova linha
		for(String[] st : getProdutos().getDadosJTableApenasPesquisa(getMeuTipo())){
			modelo.addRow(st);
		}
	}
	
	/**
	 * recuperar um preco de um produto, cria um cliente e acessas as empresa correspondentes<br />
	 * recupera o id do produto da selecao no JTableProdutos e pergunta a quantidade a partir de um 
	 * InputDialog<br />
	 * Caso o id esta correto e a quantidade tambem, chama o metodo clienteGetPreco 
	 * @see clienteGetPreco
	 * */
	private void getPreco(){
		DefaultTableModel modelo = (DefaultTableModel)JTableProdutos.getModel();
		if (JTableProdutos.getSelectedRow()==-1) { apoio.Mensagens.mensagemAlerta("Selecione um produto", "Selecione"); return;}
		String id = (String)modelo.getValueAt(JTableProdutos.getSelectedRow(), 0);
		String tipoProduto = (String)modelo.getValueAt(JTableProdutos.getSelectedRow(), 1);
		String nomeProduto = (String)modelo.getValueAt(JTableProdutos.getSelectedRow(), 2);
		if (apoio.Mensagens.question("Deseja pesquisa o preco do\nProduto '"+id+"-"+nomeProduto+"' ?", "Presquisar Preco")) {
			
			try{
				_quantidadeComprar = Integer.valueOf(apoio.Mensagens.input("Digite a Quantidade: "));
			} catch (Exception err){
				apoio.Mensagens.mensagemErro("Quantidade invalida", "Quantidade"); return;
			}
			if (_quantidadeComprar <= 0) { apoio.Mensagens.mensagemErro("Quantidade invalida", "Quantidade"); return;}
			Tipo tpProduto = Tipos.IntTipo(Integer.valueOf(tipoProduto));
			clienteGetPreco(Integer.valueOf(id), tpProduto);
		}
	}
	
	/**
	 * Acessa os servidores e realiza a consulta de precos, reputacao e disponibilidade<br />
	 * depois escolhe a empresa de acordo com a reputacao e preco, faz a requisicao para a empresa contemplada<br />
	 * e espera o retorna da requisicao, se for atendida atualiza o historico de compra e diminui o caixa interno<br />
	 * se nao for atendido, atualiza o historico de confiabiliadde
	 * @idProduto id do produto de pesquisa
	 * @tipoProduto tipo de produto a ser pesquisado
	 * @see analiseDeReputacao, Comprar
	 * */
	private void clienteGetPreco(int idProduto, Tipo tipoProduto){
		List<Dados> dados = new ArrayList<Dados>(); //_dados.clear();
		List<Empresas> empresasRamo = new Empresas().getEmpresasRamo(tipoProduto);
		int totalEmpresasRequisicao = empresasRamo.size(); //total de empresas da requisicao
		dados = new ArrayList<Dados>(totalEmpresasRequisicao);
		
		for(Empresas e : empresasRamo){
			Registry registry;
			try {
				registry = LocateRegistry.getRegistry(e.getIp(), e.getPorta()); /*ip, porta*/
				IntAtacado _msg = (IntAtacado) registry.lookup(e.getNome()); //"Encomendas"
				if (_msg==null) {printMensagensCliente("houve um erro"); totalEmpresasRequisicao--; continue;}
				
				//disponibilidade
				printMensagensCliente("Disponibilidade: " + e.getNome() + " - " + e.getRamo() + " ["+e.getIp()+":"+e.getPorta()+"]");
				int disponibilidade = _msg.getDisponibilidade(idProduto);
				printMensagensCliente("Disponibilidade: " + e.getNome() + " - " + e.getRamo() + " - estoque: " + String.valueOf(disponibilidade));
				
				if (disponibilidade <= 0) { totalEmpresasRequisicao--; continue;}
				
				//getPrecoProduto
				printMensagensCliente("Busca Preco: " + e.getNome() + " - " + e.getRamo() + " ["+e.getIp()+":"+e.getPorta()+"]");
				double preco = _msg.getPrecoProduto(idProduto);
				printMensagensCliente("Empresa: " + e.getNome() + " - " + e.getRamo() + " - preco: " + String.valueOf(preco));
				
				//getReputacaoLoja
				printMensagensCliente("busca reputacao: " + e.getNome() + " - " + e.getRamo() + " ["+e.getIp()+":"+e.getPorta()+"]");
				double reputacao = analiseDeReputacao(e.getNome(), e.getRamo());
				printMensagensCliente("Empresa: " + e.getNome() + " - " + e.getRamo() + " - reputacao: " + String.valueOf(reputacao));
				
				Produtos pPesquisa = new Produtos();
				pPesquisa.setCodigo(idProduto);
				pPesquisa.setTipoProduto(tipoProduto);
				pPesquisa = (Produtos) new TxtIObj(pPesquisa).getIObj(idProduto);

				Produtos p = new Produtos();
				p.setCodigo(idProduto);
				p.setQuantidade(disponibilidade);
				p.setValor(preco);
				p.setTipoProduto(tipoProduto);
				p.setNome(pPesquisa.getNome());
				p.setQuantidade(_quantidadeComprar);
				dados.add(new Dados(e,p,reputacao, disponibilidade));
				
				totalEmpresasRequisicao--;
				//com base na reputacao e no preco decide por quem vai comprar
				if (totalEmpresasRequisicao <= 0) { //analise dos precos e reputacoes levantadas
					Comprar(dados);
				}
				
			} 
			catch (NotBoundException ex) { ex.printStackTrace(); } 
			catch (NumberFormatException ex) { ex.printStackTrace(); } 
			catch (RemoteException ex) { ex.printStackTrace(); }
			catch (Exception ex) { ex.printStackTrace(); }
		}
	
	}
	
	/**
	 * usa o metodo getEmpresasPedirReputacao() da classe Empresas, que retorna uma lista de empresas
	 * que sao diferentes do meu ramo e diferentes do ramo da empresa a ser buscada
	 * @nomeEmpresa nome da empresa que de busca da reputacao
	 * @ramoBusca ramo da empresa
	 * @see Empresas, getEmpresasPedirReputacao
	 * @return retorna a menor das reputacoes da empresa
	 * */
	private double analiseDeReputacao(String nomeEmpresa, Tipo ramoBusca){
		double reputacao = 1.0;
		List<Empresas> empresasPedirReputacao = new Empresas().getEmpresasPedirReputacao(getMeuTipo(), ramoBusca);
		double[] reputacoes = new double[empresasPedirReputacao.size()];
		int i = 0;
		
		for(Empresas e : empresasPedirReputacao){
			Registry registry;
			try {
				registry = LocateRegistry.getRegistry(e.getIp(), e.getPorta()); /*ip, porta*/
				IntAtacado _msg = (IntAtacado) registry.lookup(e.getNome()); //"Encomendas"
				if (_msg==null) {printMensagensCliente("houve um erro"); i++; continue;}
				
				//busca reputacao da empresa
				printMensagensCliente("Pedir Reputacao para: " + e.getNome() + " - " + e.getRamo() + " ["+e.getIp()+":"+e.getPorta()+"], da empresa: " + nomeEmpresa);
				reputacoes[i] = _msg.getReputacaoLoja(nomeEmpresa);
				printMensagensCliente("Reputacao da empresa "+nomeEmpresa+": " + reputacao);

				i++;
			} catch (NotBoundException ex) { } catch (NumberFormatException ex) { ex.printStackTrace(); } catch (RemoteException ex) { ex.printStackTrace(); }
		}
		
		i = 0;
		//retorna a menor reputacao da empresa ou a media ?
		//vou retornar a menor
		for(i = 0; i < reputacoes.length; i++){
			if (i == 0) {
				reputacao = reputacoes[i];
			} else {
				//recupera a menor das reputacoes da empresa
				if (reputacao > reputacoes[i]) {
					reputacao = reputacoes[i];
				}
			}
		}
		
		return reputacao;
	}
	
	/**
	 * ESCOLHE A EMPRESA, ENTRA EM CONTATO E REALIZA O PEDIDO DE COMPRA,
	 * espera a resposta e se for atendida atualiza o historico de compra e diminui o caixa interno<br />
	 * se nao for atendido, atualiza o historico de confiabiliadde
	 * @dados dados das empresas que possuem o produto a ser comprado
	 * */
	private void Comprar(List<Dados> dados){
		if (dados==null || dados.size() <= 0) return;
		
		//deve escolher o de menor preco e de maior reputacao
		Dados escolhido = null;
		double avaliacao = 0.0;
		for (Dados d : dados) {
			if (avaliacao==0) {
				avaliacao = FuncaoPrecoReputacao(d.produto.getValor(), d.reputacao);
				escolhido = d;
			} else {
				double aval2 = FuncaoPrecoReputacao(d.produto.getValor(), d.reputacao);
				if (aval2 < avaliacao) {
					avaliacao = aval2;
					escolhido = d;
				}
			}
			//System.out.println("Analisar Dados de: " + d.toString());
		}
		
		if (escolhido == null) return;
		printMensagensCliente("-----------------------");
		printMensagensCliente("Avaliacao: " + avaliacao);
		printMensagensCliente("Escolhido: " + escolhido.toString());
		
		Registry registry;
		try {
			registry = LocateRegistry.getRegistry(escolhido.empresa.getIp(), escolhido.empresa.getPorta()); /*ip, porta*/
			IntAtacado _msg = (IntAtacado) registry.lookup(escolhido.empresa.getNome()); //"Encomendas"
			if (_msg==null) {printMensagensCliente("houve um erro"); return;}
			
			//comprar
			printMensagensCliente("Comprar: " + escolhido.empresa.getNome() + " - " + escolhido.empresa.getRamo() + " ["+escolhido.empresa.getIp()+":"+escolhido.empresa.getPorta()+"]");
			boolean atende = _msg.comprar(escolhido.produto.getCodigo(), _quantidadeComprar);
			printMensagensCliente("Comprar: " + escolhido.empresa.getNome() + " - " + escolhido.empresa.getRamo() + " - atende: " + String.valueOf(atende));
			
			if (atende) {
				histCompra(escolhido);
				
				double vlrPagar = _quantidadeComprar * escolhido.produto.getValor();
				
				apoio.Mensagens.mensagemInfo("Compra atendida, valor a ser pago: " + vlrPagar, "Compra");
				double vlrCaixa = Double.valueOf(txtCaixa.getText());
				double caixaAtual = vlrCaixa - vlrPagar;
				apoio.Mensagens.mensagemInfo("Caixa atualizado para: " + caixaAtual, "Caixa");
				txtCaixa.setText(String.valueOf(caixaAtual));
				
				tabbedPane.setSelectedComponent(pnlServer);
			} else {
				histConfi(escolhido);
				apoio.Mensagens.mensagemAlerta("Compra nao atendida", "Compra");
			}
			
			showHistoricos();
			
		} catch (NotBoundException ex) { } catch (NumberFormatException ex) { ex.printStackTrace(); } catch (RemoteException ex) { ex.printStackTrace(); }
		
	}
	
	/**
	 * @preco preco do produto na empresa
	 * @reput reputacao da empresa
	 * @return uma funcao de avaliacao, na qual quanto menor o preco e maior a reputacao, 
	 * maior a saida da funcao
	 * */
    private double FuncaoPrecoReputacao(double preco, double reput){
    	return (1/preco)*.30 + reput*.7;
    }
	
    /**
     * insere um dado no historico de confiabilidade
     * @d dado da empresa
     * */
    private void histConfi(Dados d){
		HistoricoConfiabilidade hc = new HistoricoConfiabilidade();
		TxtIObj tx = new TxtIObj(hc);
		hc.setCodigo(tx.proximoCodigoCadastro());
		hc.setNomeEmpresa(d.empresa.getNome());
		hc.setIdProduto(d.produto.getCodigo());
		hc.setNomeProduto(d.produto.getNome());
		hc.setTipoEmpresa(d.empresa.getRamo());
		tx.Cadastrar();
    }
    
    /**
     * insere um dado no historico de compra
     * @d dado da empresa
     * */
    private void histCompra(Dados d){
		HistoricoCompras hc = new HistoricoCompras();
		TxtIObj tx = new TxtIObj(hc);
		hc.setCodigo(tx.proximoCodigoCadastro());
		hc.setNomeEmpresa(d.empresa.getNome());
		hc.setIdProduto(d.produto.getCodigo());
		hc.setNomeProduto(d.produto.getNome());
		hc.setTipoEmpresa(d.empresa.getRamo());
		tx.Cadastrar();    	
    }
		
	/**
	 * imprime mensagens do server no console ou envia para um JTextArea
	 * */
	@SuppressWarnings("unused")
	private void printMensagensServidor(String msg){
		if (txtMensagensServidor != null) {
			txtMensagensServidor.setText(msg + "\n" +txtMensagensServidor.getText());
		} else {
			System.out.println(msg);
		}
	}
	
	/**
	 * imprime mensagens do cliente no console ou envia para um JTextArea
	 * */
	private void printMensagensCliente(String msg){
		if (txtRespostasCliente != null) {
			txtRespostasCliente.setText(msg + "\n" +txtRespostasCliente.getText());
		} else {
			System.out.println(msg);
		}
	}
	
    /**
     * teste de criacao de varios servidores
     * */
	private static void testeVariosServidores(){
		
		List<Empresas> em = new Empresas().getTodasEmpresas();
		frmServerTeste[] frms = new frmServerTeste[em.size()-1];
		int i = 0;
		for(Empresas e: em){
			if (!e.getNome().equals("Livraria1")){ //no caso esta empresa sou eu
				frms[i] = new frmServerTeste();
				frms[i].setEmpresa(e);
				frms[i].setVisible(true);
				frms[i].iniciaServer();
				i++;
			}
		}
	
	}
	
}

/**
 * informacoes de dados de produtos, reputacao, empresa
 * @author Emerson Shigueo Sugimoto
 * */
class Dados {
	Empresas empresa;
	Produtos produto;
	double reputacao;
	int disponibilidade;
	
	public Dados(Empresas e, Produtos p, double r, int d){
		empresa = e;
		produto = p;
		reputacao = r;
		disponibilidade = d;
	}
	
	@Override
	public String toString() {
		return empresa.getNome()+"-"+empresa.getRamo()+"-"+produto.getCodigo()+","+produto.getValor()+",rep:"+reputacao+",dispon:"+disponibilidade;
	}
}